﻿using System;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Threading;

namespace Dare.Utilities.Net
{
    /// <summary>
    /// HttpClient class
    /// </summary>
    public class HttpClient
    {
        #region Member Fields
        private CookieContainer _cc = new CookieContainer();
        private WebProxy _proxy;

        private string _lastUrl = string.Empty;
        private string reqUserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; InfoPath.2)";

        private int tryDelayTime;

        public int TryDelayTime
        {
            get { return tryDelayTime; }
            set
            {
                if (value >= 0)
                { tryDelayTime = value; }
            }
        }


        private int tryTimes;

        public int TryTimes
        {
            get { return tryTimes; }
            set
            {
                if (value > 0)
                {
                    tryTimes = value;
                }
            }
        }


        private int timeout;

        public int Timeout
        {
            get { return timeout; }
            set
            {
                if (value > 0)
                {
                    timeout = value;
                }
            }
        }

        private Exception lastException;

        public Exception LastException
        {
            get { return lastException; }
            set { lastException = value; }
        }

        private Encoding encoding;

        public Encoding Encoding
        {
            get { return encoding; }
            set { encoding = value; }
        }

        #endregion

        public HttpClient()
        {
            tryDelayTime = 0;   //0s
            tryTimes = 2;       //2times
            timeout = 30000;    //30s
            encoding = Encoding.UTF8;
        }

        // 无 referer 的 POST  // by hook.hu@gmail.com
        public string Post(string url, string content)
        {
            string data = Post(url, content, _lastUrl);
            _lastUrl = url;
            return data;
        }

        /// <summary>
        /// Send post data to server
        /// </summary>
        /// <param name="url"></param>
        /// <param name="content"></param>
        /// <returns>Return content</returns>
        public string Post(string url, string content, string referer)
        {
            lastException = null;
            int failedTimes = TryTimes;
            while (failedTimes-- > 0)
            {
                try
                {
                    DelaySomeTime();

                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url));
                    req.UserAgent = reqUserAgent;
                    req.CookieContainer = _cc;
                    req.Referer = referer;
                    byte[] buff = this.Encoding.GetBytes(content);
                    req.Method = "POST";
                    req.Timeout = Timeout;
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.ContentLength = buff.Length;
                    if (null != _proxy && null != _proxy.Credentials)
                    {
                        req.UseDefaultCredentials = true;
                    }
                    req.Proxy = _proxy;
                    //req.Connection = "Keep-Alive";
                    Stream reqStream = req.GetRequestStream();
                    reqStream.Write(buff, 0, buff.Length);
                    reqStream.Close();

                    //接收返回字串
                    HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                    StreamReader sr = new StreamReader(res.GetResponseStream(), this.Encoding, true);
                    return sr.ReadToEnd();
                }
                catch (Exception ex)
                {
                    lastException = ex;
                }
            }

            return null;
        }

        private void DelaySomeTime()
        {
            if (tryDelayTime > 0)
            {
                Random rd = new Random();
                int delayTime = tryDelayTime * 1000 + rd.Next(1000);
                Thread.Sleep(delayTime);
            }
        }

        // 无 referer 的 POST  // by hook.hu@gmail.com
        public string Get(string url)
        {
            string data = Get(url, _lastUrl);
            _lastUrl = url;
            return data;
        }
        
        /// <summary>
        /// Get data from server
        /// </summary>
        /// <param name="url"></param>
        /// <returns>Return content</returns>
        public string Get(string url, string referer)
        {
            int failedTimes = TryTimes;
            while (failedTimes-- > 0)
            {
                try
                {
                    DelaySomeTime();

                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url));
                    req.UserAgent = reqUserAgent;
                    req.CookieContainer = _cc;
                    req.Referer = referer;

                    req.Method = "GET";
                    req.Timeout = Timeout;
                    if (null != _proxy && null != _proxy.Credentials)
                    {
                        req.UseDefaultCredentials = true;
                    }
                    req.Proxy = _proxy;
                    //req.Connection = "Keep-Alive";

                    //接收返回字串
                    HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                    StreamReader sr = new StreamReader(res.GetResponseStream(), this.Encoding, true);
                    return sr.ReadToEnd();
                }
                catch (Exception ex)
                {
                    lastException = ex;
                }
            }

            return null;
        }

        /// <summary>
        /// Set Proxy
        /// </summary>
        /// <param name="server"></param>
        /// <param name="port"></param>
        public void SetProxy(string server, int port, string username, string password)
        {
            if (null != server && port > 0)
            {
                _proxy = new WebProxy(server, port);
                if (null != username && null != password)
                {
                    _proxy.Credentials = new NetworkCredential(username, password);
                    _proxy.BypassProxyOnLocal = true;
                }
            }
        }



        /// <summary>
        /// Encode post data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string EncodePostData(string data)
        {
            return HttpUtility.UrlEncode(data);
        }


    }
}
